// Table.cpp: implementation of the CTable class.
//
//////////////////////////////////////////////////////////////////////


#include "Table.h"

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "iface.h"
#include "Buffer.h"
#include <sys/time.h>

//#include <config.h>

extern	unsigned short	actcode; //from rcinput
extern	unsigned short	realcode; //from rcinput
extern	int				doexit;

#define T_ROWS		2
#define T_COLS		9

static int 	win_counter 	= 0;
int 		ShowCards 	= 3;
	
typedef enum {
	SL_BLOCK = 0,
	SL_WASTEPILE1,
	SL_WASTEPILE2,
	SL_WASTEPILE3,
	SL_WASTEPILE4,
	SL_COUNT } t_slots;
    
class CTableGrid
{
public:
//	CHand			hand;
	CBlock			block;
	CWastepile		wastepile[4];
	bool			changed[5];
	SlotPos			layouts[L_COUNT][SL_COUNT];
	t_slots   		act_slot;
	
	void SetAllChanged( bool _changed )
	{
		for( unsigned int i = 0; i < sizeof( changed ); i++ )
		{
			changed[i] = _changed;
		}
	}
	
	CTableGrid()
	{
		int left = 0;
		int top = 0;
		act_slot = SL_BLOCK;
		SetAllChanged(true);		
	//fill layouts
		
		// 800x600
		layouts[L800X600][SL_BLOCK] = SlotPos( left +19, top, 0, 0 );
		layouts[L800X600][SL_WASTEPILE1] = SlotPos( left +95, top, 0, 0 );
		layouts[L800X600][SL_WASTEPILE1] = SlotPos( left +195, top, 0, 0 );
		layouts[L800X600][SL_WASTEPILE1] = SlotPos( left +295, top, 0, 0 );
		layouts[L800X600][SL_WASTEPILE1] = SlotPos( left +395, top, 0, 0 );
		
		// 600x800
		layouts[L600X800][SL_BLOCK] = SlotPos( left +19, top, 0, 0 );
		layouts[L600X800][SL_WASTEPILE1] = SlotPos( left +95, top, 0, 0 );
		layouts[L600X800][SL_WASTEPILE1] = SlotPos( left +195, top, 0, 0 );
		layouts[L600X800][SL_WASTEPILE1] = SlotPos( left +295, top, 0, 0 );
		layouts[L600X800][SL_WASTEPILE1] = SlotPos( left +395, top, 0, 0 );
	
	}
};

void CTable::Deal()
{
	if( 0 == grid->block.GetCardsStored() )
	{
		return;
	}

	std::cout << inf << "deal" << std::endl;
	
	for( int i = 0; i < 4; i++ )
	{
		CCard tmp( grid->block.PopCard() );
		tmp.Flip();
		grid->wastepile[i].PushCard( tmp );
	}
	
	grid->changed[ SL_WASTEPILE1 ] = true;
	grid->changed[ SL_WASTEPILE2 ] = true;
	grid->changed[ SL_WASTEPILE3 ] = true;
	grid->changed[ SL_WASTEPILE4 ] = true;
	
	grid->changed[ SL_BLOCK ] = true;
	grid->act_slot = SL_WASTEPILE1;

	ChangeSelection( );
}

CTable::CTable()
{

	this->grid = new CTableGrid();
	


	layout = L800X600;
	
	Load();
}

CTable::~CTable()
{
	Save();
}

void CTable::Init()
{


	unsigned char i = 0;

	win_counter = 0;
	game_over = false;
	scores	= 0;

	grid->act_slot = SL_BLOCK;
	grid->SetAllChanged(true);

	std::cout << inf << "Remove all cards from Block" << std::endl;
	grid->block.RemoveAll();
	std::cout << inf << "Fill the Block" << std::endl;
	grid->block.Fill();

	std::cout << inf << "Shuffle" << std::endl;
	for( i = 0; i < 7; i++ )
		grid->block.Shuffle();

	std::cout << inf << "cleanup wastepiles" << std::endl;
	for( i = 0; i < 4; i++ )
		grid->wastepile[i].RemoveAll();

	Deal();

	grid->act_slot = SL_WASTEPILE1;

	ChangeSelection( true );

}

void CTable::MoveCursor( t_direction _direction)
{
	this->ChangeSelection( false );

	switch( grid->act_slot )
	{
	case SL_BLOCK :
			switch( _direction )
			{
			case DIR_LEFT: grid->act_slot = SL_WASTEPILE4; break;
			case DIR_RIGHT: grid->act_slot = SL_WASTEPILE1; break;
			case DIR_UP: grid->act_slot = SL_WASTEPILE2; break;
			case DIR_DOWN: grid->act_slot = SL_WASTEPILE3; break;
			} break;
	case SL_WASTEPILE1 :
			switch( _direction )
			{
			case DIR_LEFT: grid->act_slot = SL_BLOCK; break;
			case DIR_RIGHT: grid->act_slot = SL_WASTEPILE2; break;
			case DIR_UP: grid->act_slot = SL_WASTEPILE4; break;
			case DIR_DOWN: grid->act_slot = SL_WASTEPILE3; break;
			} break;
	case SL_WASTEPILE2 :
			switch( _direction )
			{
			case DIR_LEFT: grid->act_slot = SL_WASTEPILE1; break;
			case DIR_RIGHT: grid->act_slot = SL_WASTEPILE3; break;
			case DIR_UP: grid->act_slot = SL_BLOCK; break;
			case DIR_DOWN: grid->act_slot = SL_WASTEPILE4; break;
			} break;
	case SL_WASTEPILE3 :
			switch( _direction )
			{
			case DIR_LEFT: grid->act_slot = SL_WASTEPILE2; break;
			case DIR_RIGHT: grid->act_slot = SL_WASTEPILE4; break;
			case DIR_UP: grid->act_slot = SL_WASTEPILE1; break;
			case DIR_DOWN: grid->act_slot = SL_BLOCK; break;
			} break;
	case SL_WASTEPILE4 :
			switch( _direction )
			{
			case DIR_LEFT: grid->act_slot = SL_WASTEPILE3; break;
			case DIR_RIGHT: grid->act_slot = SL_BLOCK; break;
			case DIR_UP: grid->act_slot = SL_WASTEPILE2; break;
			case DIR_DOWN: grid->act_slot = SL_WASTEPILE1; break;
			} break;
	default:
		std::cout << err << "unhandled slot in MoveCursor!" << std::endl;
		throw "Unhandled slot in MoveCursor!";
	}


	this->ChangeSelection( true );
}

void CTable::Save()
{ /*
	FILE* sav = fopen( GAMESDIR "/solitair.sav", "wb" );

	if( sav == NULL ) return;

	fwrite( &ShowCards, 1, sizeof( ShowCards ), sav );

	fwrite( &win_counter, 1, sizeof( win_counter ), sav );

	//Save BLOCK
	unsigned char CardsStored = block.GetCardsStored();

	fwrite( &CardsStored, 1, sizeof( CardsStored ), sav );

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		CCard card = block.PopCard();
		fwrite( &card, 1, sizeof( card ), sav );
	}

	//save WASTEPILE
	CardsStored = wastepile.GetCardsStored();

	fwrite( &CardsStored, 1, sizeof( CardsStored ), sav );

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		CCard card = wastepile.PopCard();
		fwrite( &card, 1, sizeof( card ), sav );
	}

	//Save HAND
	int HSource = 0;

	if( &block == hand.GetSource() )
	{
		HSource = SL_BLOCK;
	}
	else
	if( &wastepile == hand.GetSource() )
	{
		HSource = WASTEPILE;
	}
	else
	if( &foundation[0] == hand.GetSource() )
	{
		HSource = FOUNDATION1;
	}
	else
	if( &foundation[1] == hand.GetSource() )
	{
		HSource = FOUNDATION2;
	}
	else
	if( &foundation[2] == hand.GetSource() )
	{
		HSource = FOUNDATION3;
	}
	else
	if( &foundation[3] == hand.GetSource() )
	{
		HSource = FOUNDATION4;
	}
	else
	if( &tableau[0] == hand.GetSource() )
	{
		HSource = TABLEAU1;
	}
	else
	if( &tableau[1] == hand.GetSource() )
	{
		HSource = TABLEAU2;
	}
	else
	if( &tableau[2] == hand.GetSource() )
	{
		HSource = TABLEAU3;
	}
	else
	if( &tableau[3] == hand.GetSource() )
	{
		HSource = TABLEAU4;
	}
	else
	if( &tableau[4] == hand.GetSource() )
	{
		HSource = TABLEAU5;
	}
	else
	if( &tableau[5] == hand.GetSource() )
	{
		HSource = TABLEAU6;
	}
	else
	if( &tableau[6] == hand.GetSource() )
	{
		HSource = TABLEAU7;
	}

	fwrite( &HSource, 1, sizeof( HSource ), sav );

	CardsStored = hand.GetCardsStored();

	fwrite( &CardsStored, 1, sizeof( CardsStored ), sav );

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		CCard card = hand.PopCard();
		fwrite( &card, 1, sizeof( card ), sav );
	}

	//Save Tableaus
	for( int j = 0; j < 7; j++ )
	{
		CardsStored = tableau[j].GetCardsStored();

		fwrite( &CardsStored, 1, sizeof( CardsStored ), sav );

		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			CCard card = tableau[j].PopCard();
			fwrite( &card, 1, sizeof( card ), sav );
		}
	}

	//Save Foundations
	for( int j = 0; j < 4; j++ )
	{
		CardsStored = foundation[j].GetCardsStored();

		fwrite( &CardsStored, 1, sizeof( CardsStored ), sav );

		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			CCard card = foundation[j].PopCard();
			fwrite( &card, 1, sizeof( card ), sav );
		}
	}

	fclose( sav );
*/
}

void CTable::Load()
{
/*
	int SavShowCards = 0;

	FILE* sav = fopen( GAMESDIR "/solitair.sav", "rb" );

	if( sav == NULL ) return;

	fread( &SavShowCards, 1, sizeof( SavShowCards ), sav );

	if( ( SavShowCards != 3 ) && ( SavShowCards != 1 ) )
	{
		return;
	}

	ShowCards = SavShowCards;

	fread( &win_counter, 1, sizeof( win_counter ), sav );

	CCard card;
	unsigned char CardsStored;
	CBuffer buffer;


//Restore BLOCK

	block.RemoveAll();

	fread( &CardsStored, 1, sizeof( CardsStored ), sav );

	buffer.RemoveAll();
	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		fread( &card, 1, sizeof( card ), sav );
		buffer.PushCard( card, true );
	}

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		block.PushCard( buffer.PopCard(), true );
	}

//Restore Wastepile
	fread( &CardsStored, 1, sizeof( CardsStored ), sav );

	buffer.RemoveAll();
	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		fread( &card, 1, sizeof( card ), sav );
		buffer.PushCard( card, true );
	}

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		wastepile.PushCard( buffer.PopCard(), true );
	}
//Restore HAND
	int HSource;
	fread( &HSource, 1, sizeof( HSource ), sav );

	switch( HSource )
	{
		case 0:
			hand.SetSource(NULL);
			break;
		case SL_BLOCK:
			hand.SetSource(&block);
			break;
		case SL_WASTEPILE:
			hand.SetSource(&wastepile);
			break;
		case SL_FOUNDATION1:
			hand.SetSource(&foundation[0]);
			break;
		case SL_FOUNDATION2:
			hand.SetSource(&foundation[1]);
			break;
		case SL_FOUNDATION3:
			hand.SetSource(&foundation[2]);
			break;
		case SL_FOUNDATION4:
			hand.SetSource(&foundation[3]);
			break;
		case SL_TABLEAU1:
			hand.SetSource(&tableau[0]);
			break;
		case SL_TABLEAU2:
			hand.SetSource(&tableau[1]);
			break;
		case SL_TABLEAU3:
			hand.SetSource(&tableau[2]);
			break;
		case SL_TABLEAU4:
			hand.SetSource(&tableau[3]);
			break;
		case SL_TABLEAU5:
			hand.SetSource(&tableau[4]);
			break;
		case SL_TABLEAU6:
			hand.SetSource(&tableau[5]);
			break;
		case SL_TABLEAU7:
			hand.SetSource(&tableau[6]);
			break;
	}


	fread( &CardsStored, 1, sizeof( CardsStored ), sav );

	buffer.RemoveAll();
	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		fread( &card, 1, sizeof( card ), sav );
		buffer.PushCard( card, true );
	}

	for( unsigned char i = 0; i < CardsStored; i++ )
	{
		hand.PushCard( buffer.PopCard(), true );
	}

//Restore Tableaus
	for( int j = 0; j < 7; j++ )
	{
		fread( &CardsStored, 1, sizeof( CardsStored ), sav );

		buffer.RemoveAll();
		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			fread( &card, 1, sizeof( card ), sav );
			buffer.PushCard( card, true );
		}

		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			tableau[j].PushCard( buffer.PopCard(), true );
		}
	}
//Restore Foundations
	for( int j = 0; j < 4; j++ )
	{
		fread( &CardsStored, 1, sizeof( CardsStored ), sav );

		buffer.RemoveAll();
		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			fread( &card, 1, sizeof( card ), sav );
			buffer.PushCard( card, true );
		}

		for( unsigned char i = 0; i < CardsStored; i++ )
		{
			foundation[j].PushCard( buffer.PopCard(), true );
		}
	}


	fclose( sav );
*/
}

/*
int CTable::Run()
{

//	BBSetBackground( BACK_C );

//	FBCopyImage( 0, 0, WIDTH, HEIGHT, BBGetData() );

//	FBDrawString( 300, 255, 42, "Loading...", 250, 0 );

	//Outer loop for initialization
	while( 0 == doexit )
	{

//		this->Init();

		this->Display();

		//Inner loop for game controlling
		while( 0 == doexit )
		{
			//Handle keys
			this->HandleKeysPressed();

			if( 0 != doexit ) break;

			//Display changes
		}
	}

	return 0;
}
*/
void CTable::ShowHelp()
{
/*
	const int Hx = 100;
	const int Hy = 100;
	const int Hwidth = 520;
	const int Hheight = 376;

	FBFillRect( Hx+8, Hy+8, Hwidth, Hheight, Convert_24_8( 0,0,0) );
	FBFillRect( Hx, Hy, Hwidth, Hheight, 19 );

	FBDrawHLine( Hx + 5, Hy + 55, 400, Convert_24_8( 255,255,255) );
	FBDrawHLine( Hx + 5, Hy + 56, 400, Convert_24_8( 255,255,255) );

	FBDrawString( Hx + 5, Hy + 5, 48, "Solitair for D-BOX", Convert_24_8( 255,255,255), 0 );

	FBDrawString( Hx + 5, Hy + 60, 32, "TheMoon, 2003", Convert_24_8( 255,255,255), 0 );

	FBDrawString( Hx + 5, Hy + 102, 32, "Key mappings:", Convert_24_8( 255,255,255), 0 );

	FBDrawString( Hx + 5, Hy + 135, 32, "(Red)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 135, 32, "- Restart game", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 168, 32, "(Blue)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 168, 32, "- Wizard", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 201, 32, "(?)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 201, 32, "- Help screen", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 234, 32, "(Home)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 234, 32, "- Exit", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 267, 32, "(1 - 7)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 267, 32, "- Tableau", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 300, 32, "(-) (+)", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 300, 32, "- Change selection", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 5, Hy + 333, 32, "DBOX", Convert_24_8( 255,255,255), 0 );
	FBDrawString( Hx + 105, Hy + 333, 32, "- Setup menu", Convert_24_8( 255,255,255), 0 );
*/


}

bool CTable::Relayout()
{
	// check width and height and relocate Slots accordently
	
	int scrwidth 	= this->ScreenWidth();
	int scrheight 	= this->ScreenHeight();
	int orient      = this->GetOrientation();
	
	std::cout << inf << "CTable::Relayout:" << "\n" 
		<< "\t" << "screen width: " << scrwidth << "\n"
		<< "\t" << "screen height: " << scrheight << "\n"
		<< "\t" << "screen orientation: " << orient << "\n"
	<< std::endl;	

	if( scrwidth == 600 )
		layout = L600X800;
	else
		layout = L800X600;
		
	Display(true);
	
	return true;
}

bool CTable::Setup()
{
	bool ret = true;
	if( ret )
		ret = this->Relayout();
	return true;
}

void CTable::Handle(t_doing _doing)
{
	static bool	HelpOnScreen = false;
//	static bool	MenuOnScreen = false;

	if( true == HelpOnScreen )
	{
//		FBCopyImage( 0, 0, WIDTH, HEIGHT, BBGetData() );
		HelpOnScreen = false;
		return;
	}

	switch( _doing )
	{
 		case DO_SEL_0 :

			ChangeSelection( false );
			grid->changed[ grid->act_slot ] = true;
			grid->changed[ SL_BLOCK ] = true;
			grid->act_slot = SL_BLOCK;
			ChangeSelection( );


			break;
		case DO_SEL_1 :

			ChangeSelection( false );
			grid->changed[ grid->act_slot ] = true;
			grid->changed[ SL_WASTEPILE1 ] = true;
			grid->act_slot = SL_WASTEPILE1;
			ChangeSelection( true, false );

			break;
		case DO_SEL_2 :
			ChangeSelection( false );
			grid->changed[ grid->act_slot ] = true;
			grid->changed[ SL_WASTEPILE2 ] = true;
			grid->act_slot = SL_WASTEPILE2;
			ChangeSelection( true, false );

			break;
		case DO_SEL_3 :
			ChangeSelection( false );
			grid->changed[ grid->act_slot ] = true;
			grid->changed[ SL_WASTEPILE3 ] = true;
			grid->act_slot = SL_WASTEPILE3;
			ChangeSelection( true, false );

			break;
		case DO_SEL_4 :
			ChangeSelection( false );
			grid->changed[ grid->act_slot ] = true;
			grid->changed[ SL_WASTEPILE4 ] = true;
			grid->act_slot = SL_WASTEPILE4;
			ChangeSelection( true, false );

			break;
		case DO_SEL_5 :

			break;
		case DO_SEL_6 :

			break;
		case DO_SEL_7 :

			break;
		case DO_SEL_8 :

			break;
		case DO_SEL_9 :

			break;

		case DO_MOVERIGHT :
			this->MoveCursor( DIR_RIGHT );
			break;
		case DO_MOVELEFT :
			this->MoveCursor( DIR_LEFT );
			break;
		case DO_MOVEUP :
			this->MoveCursor( DIR_UP );
			break;
		case DO_MOVEDOWN :
			this->MoveCursor( DIR_DOWN );
			break;
		case DO_ACTION :
			this->DoAction();
			break;
		case DO_INIT	 :
			this->Init();
			break;
		case DO_WIZARD :
			Wizard();
			break;
		case DO_SELPLUS :
			break;
		case DO_SELMINUS :
			break;
		case DO_HELP :

			this->ShowHelp();
			HelpOnScreen = true;

			break;
		case DO_RELAYOUT :
			this->Relayout();
			Display( true );
			break;
		case DO_SETUP :
			if( this->Setup() )
				this->Init();
			//FBCopyImage( 0, 0, WIDTH, HEIGHT, BBGetData() );
			Display( true );
			break;

		default:
			return;

			break;
	}

	Display();
		

}


#define TOP	25
#define LEFT	25

void CTable::Display( bool _full_update )
{

	bool some_changes = _full_update;
	
	if( _full_update )
	{
		grid->SetAllChanged(true);
		CIface::ClearScreen();
	}
	std::cout << inf << "CTable::Display("<< _full_update << ")" << std::endl;
	
	if( grid->changed[ SL_BLOCK ] )
	{
//
		some_changes = true;
		grid->block.Draw( LEFT + 15, TOP, SL_BLOCK == grid->act_slot );
	}

	int i;

	for( i = 0; i < 4; i++ )
	{
		if( grid->changed[ SL_WASTEPILE1 + i ] )
		{
			grid->wastepile[i].Draw( LEFT+(1+i)*80, TOP, (SL_WASTEPILE1 + i) == grid->act_slot );
			some_changes = true;
		}
	}

	grid->SetAllChanged(false);

	if( _full_update )
	{
		CIface::DrawText( "Aces Up", 30, 1 );
		CIface::FullUpdate();
	}
	else
	{
		CIface::UpdateAreas();
	}
}

//automaticly select all possible cards or deselect all cards
void CTable::ChangeSelection(bool select, bool select_all )
{

	CSlot* sel_slot = NULL;

	grid->changed[ grid->act_slot ] = true;

	switch( grid->act_slot )
	{
	case SL_BLOCK :		sel_slot = &grid->block;		break;
	case SL_WASTEPILE1 :
	case SL_WASTEPILE2 :
	case SL_WASTEPILE3 :
	case SL_WASTEPILE4 :  sel_slot = &grid->wastepile[grid->act_slot - SL_WASTEPILE1];	break;
	default:
		std::cout << err << "unhandled slot in ChangeSelection!" << std::endl;
		throw "Unhandled slot in ChangeSelection!";		
	}

	if( sel_slot )
	{
		if( select_all )
		{
			if( select )
				while( sel_slot->IncreaseSelection() );
			else
				while( sel_slot->DecreaseSelection() );
		}
		else
		{
			if( select )
				sel_slot->IncreaseSelection();
			else
				sel_slot->DecreaseSelection();
		}
	}
}

void CTable::DoAction()
{
	switch( grid->act_slot )
	{
	case SL_BLOCK :
		/* deal 4 cards to wastepiles */

		Deal();

		return;

	case SL_WASTEPILE1 :
	case SL_WASTEPILE2 :
	case SL_WASTEPILE3 :
	case SL_WASTEPILE4 :
	
		// pick the cards from wastepiles and show, if there is a card with grather value of same suit
		if( grid->wastepile[(grid->act_slot-SL_WASTEPILE1)].GetCardsStored() )
		{
			int wp_idx = grid->act_slot - SL_WASTEPILE1;
			CCard tbr( grid->wastepile[wp_idx].PeekCard() );
			
			std::cout << inf << "check for removal this card: " << wp_idx << " : " << (int)tbr.GetSuit() << "," << (int)tbr.GetValue() << std::endl;
			
			for( int i = 0; i < 4; i++ )
			{
				if( (i) != wp_idx && grid->wastepile[i].GetCardsStored() )
				{
					CCard tmp( grid->wastepile[i].PeekCard() );
					std::cout << inf << "\tcheck against this card: " << (int)tmp.GetSuit() << "," << (int)tmp.GetValue() << "," << (int)(tbr.GetValue() < tmp.GetValue()) << std::endl;
					if( tmp.GetSuit() == tbr.GetSuit() and tbr.GetValue() > tmp.GetValue() )
					{
						std::cout << inf << "OK: there is a card with same suit and greather value [" << (i) << "]" << std::endl;
						std::cout << inf << "remove the card from this wastepile : " << (int)wp_idx << std::endl;
						grid->wastepile[wp_idx].PopCard();
						grid->changed[ grid->act_slot ] = true;
						this->scores++;
						if( grid->wastepile[wp_idx].GetCardsStored() == 0 )
						{
							std::cout << inf << "the wastepile does not have any cards anymore, move cursor elsewhere" << std::endl;
							this->scores++;
							bool local_flag = false;
							for( int i = 0; i < 4; i++ )
							{
								if( grid->wastepile[i].GetCardsStored() )
								{
									std::cout << inf << "found filled wastepile, move cursor here!" << std::endl;
									grid->changed[ grid->act_slot ] = true;
									grid->changed[ (SL_WASTEPILE1 + i) ] = true;
									grid->act_slot = (t_slots)(SL_WASTEPILE1 + i);
									ChangeSelection();
									local_flag = true;
									break;
								}
							}
							if( local_flag == false )
							{
								std::cout << inf << "not found filled wastepile, move cursor to the block!" << std::endl;
							
								grid->changed[ grid->act_slot ] = true;
								grid->changed[ SL_BLOCK ] = true;
								grid->act_slot = SL_BLOCK;
								ChangeSelection();
							}
						}
						
						std::cout << inf << "Check gameover condition" << std::endl;
						//check gameover condition
						bool some_tbrs = false;
						for( int i = 0; i < 4; i++ )
						{
							CCard chk1( grid->wastepile[i].PeekCard() );
							
							for( int j = 0; j < 4; j++ )
							{
								if( i != j && grid->wastepile[j].GetCardsStored() )
								{
									CCard chk2( grid->wastepile[j].PeekCard() );
									some_tbrs |= ( chk1.GetSuit() == chk2.GetSuit() and chk1.GetValue() > chk2.GetValue() );
								}
							}
						}						
						
						if( !some_tbrs ) this->game_over = true;
						return;
					} //remove condition
				} //is not the actual slot
			} //for loop
			
			// it seems, there is no any card same suit, but may be a empty wastepile, move card overthere
			
			for( int i = 0; i < 4; i++ )
			{
				if(  grid->wastepile[i].GetCardsStored() == 0 )
				{
					//yep, we have such a empty wp
					CCard tmp( grid->wastepile[grid->act_slot-SL_WASTEPILE1].PopCard() );
					grid->wastepile[i].PushCard(tmp);
					grid->changed[ grid->act_slot ] = true;
					grid->changed[ (SL_WASTEPILE1 + i) ] = true;
				}
			}
		} //there are cards in actual slot
		else
		{
			//change selection
			bool local_flag = false;
			for( int i = 0; i < 4; i++ )
			{
				grid->wastepile[i].GetCardsStored();
				grid->changed[ grid->act_slot ] = true;
				grid->changed[ (SL_WASTEPILE1 + i) ] = true;
				grid->act_slot = (t_slots)(SL_WASTEPILE1 + i);
				ChangeSelection();
				local_flag = true;
			}
			if( local_flag == false )
			{
				grid->changed[ grid->act_slot ] = true;
				grid->changed[ SL_BLOCK ] = true;
				grid->act_slot = SL_BLOCK;
				ChangeSelection();
			}
		}
		break;
	default:
		std::cout << err << "unhandled slot in DoAction!" << std::endl;
		throw "Unhandled slot in DoAction!";		

	}

}

/* takes top card from the slot and movies it (if possible) to the foundation */
void CTable::Wizard()
{
}


void CTable::CheckWin( bool _add )
{

	if( _add )
		win_counter++;
	else
		win_counter--;



	if( win_counter == 52 )
	{
		this->Init();
	}
}

